import SparkMD5 from 'spark-md5';
const chunkSize = 5 * 1024 * 1024; //定义分片的大小 暂定为5M，方便测试

export async function uploadSliceFunc(File: File, Path: string) {
    // 获取用户选择的文件
    const file = File;
    // 文件大小 (大于100m再分片哦，否则直接走普通文件上传的逻辑就可以了，这里只实现分片上传逻辑)
    const fileSize = File.size;
  
    // 可以设置大于多少兆可以分片上传，否则走普通上传
    if (fileSize <= chunkSize) {
      console.log('上传的文件大于20m才能分片上传');
      return;
    }
  
    // 计算当前选择文件需要的分片数量
    const chunkCount = Math.ceil(fileSize / chunkSize);
    // 获取文件md5
    const fileMd5 = await getFileMd5(file, chunkCount);
  
    // 取出名字用于分片
    let fileName = file.name.substring(0, file.name.lastIndexOf('.'));
    // 取出后缀
    let nameSuffix = file.name.split('.')[file.name.split('.').length - 1];
  
    let promiseAllList: FormData[] = [];
    for (let i = 0; i < chunkCount; i++) {
      // 分片开始位置
      let start = i * chunkSize;
      // 分片结束位置
      let end = Math.min(fileSize, start + chunkSize);
      // 取文件指定范围内的byte，从而得到分片数据
      let _chunkFile = File.slice(start, end);
      // _chunkFile.name = i.toString(); // name is a read-only property
  
      let currentFileMd5 = await getFileMd5(_chunkFile as File, chunkCount);
  
      let formdata = new FormData();
      formdata.append('chunk', i.toString());
      formdata.append('chunks', chunkCount.toString()); // 分片的总数量
      formdata.append('currentFileMd5', currentFileMd5); // 分片MD5
      formdata.append('md5', fileMd5); // 文件的md5
      formdata.append('name', fileName);
      formdata.append('size', fileSize.toString());
      formdata.append('file', _chunkFile);
      formdata.append('tenantId', '');
      formdata.append('Path', Path); // 只用于分片进度的计算
  
      promiseAllList.push(formdata);
    }
  
    const paramsStr = {
      fileMd5: fileMd5, // 文件的md5
      size: File.size, // 文件总大小
      sliceTotalChunks: chunkCount, // 分片的总数量
      suffix: nameSuffix, // 后缀
      fileName: fileName, // 文件名
      promiseAllList: promiseAllList
    };
  
    return paramsStr;
  }
  
export function getFileMd5(file: File, chunkCount: number): Promise<string> {
  return new Promise((resolve, reject) => {
    const blobSlice = File.prototype.slice;
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();
    let currentChunk = 0;

    const chunkSize = Math.ceil(file.size / chunkCount);

    fileReader.onload = (e) => {
      if (e.target && e.target.result) {
        spark.append(e.target.result as ArrayBuffer);
        currentChunk++;
        if (currentChunk < chunkCount) {
          loadNext();
        } else {
          const md5 = spark.end();
          resolve(md5);
        }
      }
    };

    fileReader.onerror = (e) => {
      console.error(e);
      reject(new Error('FileReader encountered an error.'));
    };

    const loadNext = () => {
      const start = currentChunk * chunkSize;
      const end = Math.min(start + chunkSize, file.size);
      const chunk = blobSlice.call(file, start, end);
      fileReader.readAsArrayBuffer(chunk);
    };

    loadNext();
  });
}




